//////////////////////////////////////////////////////////////////////////
//
// This file is a part of UKROP project.
// Copyright (c) Vladimir Gumenuk
//
// PROJECT:         Xort Custom Debug Engine
// FILE:            Document.h : Declaration of the CDocument
// AUTHOR:          Vladimir Gumenuk
// DATE:            Dec-2012 -- Jan-2013
// MODIFICATIONS:
//
//////////////////////////////////////////////////////////////////////////

#pragma once

//////////////////////////////////////////////////////////////////////////
// CDocument, implements Document & Code contexts
class ATL_NO_VTABLE CDocument :
    public CComObjectRootEx<CComSingleThreadModel>,
    public CComCoClass<CDocument, &CLSID_Document>,
    public IDebugDocument2,
    public IDebugDocumentContext2,
    public IDebugCodeContext2,
    public IXDocument
{
public:
    CDocument();
    virtual ~CDocument();

DECLARE_REGISTRY_RESOURCEID(IDR_DOCUMENT)

BEGIN_COM_MAP(CDocument)
    COM_INTERFACE_ENTRY(IDebugDocument2)
    COM_INTERFACE_ENTRY(IDebugDocumentContext2)
    COM_INTERFACE_ENTRY(IDebugCodeContext2)
    COM_INTERFACE_ENTRY(IDebugMemoryContext2)
    COM_INTERFACE_ENTRY(IXDocument)
END_COM_MAP()

DECLARE_PROTECT_FINAL_CONSTRUCT()

    HRESULT FinalConstruct();
    void FinalRelease();

IMPLEMENT_CREATE(CDocument, IDebugDocument2);

    //////////////////////////////////////////////////////////////////////////
    // IXDocument
    // called once to initialize object
    STDMETHOD(Initialize)( LPCSTR lpszFileName );

    // Updates the position in source code
    STDMETHOD(SetPosition)( TEXT_POSITION *pPos ); 

    // Returns the current position
    STDMETHOD(GetPosition)( TEXT_POSITION *pPos );

public:
    //////////////////////////////////////////////////////////// 
    //IDebugDocument2 
    STDMETHOD(GetName)( GETNAME_TYPE gnType, __RPC__deref_out_opt BSTR *pbstrName );
    STDMETHOD(GetDocumentClassId)( __RPC__out CLSID *pclsid );

    //////////////////////////////////////////////////////////////////////////
    // IDebugDocumentContext2 
    STDMETHOD(GetDocument)( __RPC__deref_out_opt IDebugDocument2 **ppDocument);
    STDMETHOD(EnumCodeContexts)(  __RPC__deref_out_opt IEnumDebugCodeContexts2 **ppEnumCodeCxts);
    STDMETHOD(GetLanguageInfo)( __RPC__deref_opt_inout_opt BSTR *pbstrLanguage, __RPC__inout_opt GUID *pguidLanguage);
    STDMETHOD(GetStatementRange)( __RPC__inout_opt TEXT_POSITION *pBegPosition, __RPC__inout_opt TEXT_POSITION *pEndPosition);
    STDMETHOD(GetSourceRange)( __RPC__inout_opt TEXT_POSITION *pBegPosition, __RPC__inout_opt TEXT_POSITION *pEndPosition);
    STDMETHOD(Compare)( DOCCONTEXT_COMPARE compare, IDebugDocumentContext2 **rgpDocContextSet, DWORD dwDocContextSetLen, __RPC__out DWORD *pdwDocContext);
    STDMETHOD(Seek)( int nCount, __RPC__deref_out_opt IDebugDocumentContext2 **ppDocContext);

    //////////////////////////////////////////////////////////// 
    // IDebugCodeContext2 methods 
    STDMETHOD(GetDocumentContext)(IDebugDocumentContext2 **ppSrcCxt); 
    // IDebugCodeContext2 methods inherited from IDebugMemoryContext2 
    STDMETHOD(GetName)( BSTR* pbstrName ); 
    STDMETHOD(GetInfo)(CONTEXT_INFO_FIELDS dwFields, CONTEXT_INFO* pInfo); 
    STDMETHOD(Add)(UINT64 dwCount, IDebugMemoryContext2** ppMemCxt); 
    STDMETHOD(Subtract)(UINT64 dwCount, IDebugMemoryContext2** ppMemCxt); 
    STDMETHOD(Compare)( CONTEXT_COMPARE compare, IDebugMemoryContext2** rgpMemoryContextSet, DWORD dwMemoryContextSetLen, DWORD* pdwMemoryContext ); 

private:
    BSTR getFileName();

    CComBSTR    m_bsFileName;       // full path
    DWORD        m_dwCurrentLine;   // current line of code
    DWORD        m_dwCurrentColumn; // column - for future, now always 0
};

OBJECT_ENTRY_AUTO(__uuidof(Document), CDocument)
